from pyasn1.type import univ, namedtype, tag, char
from pyasn1.codec.der import encoder, decoder
import binascii


# ===== 协议版本 1 =====
class ExplicitPersonV1(univ.Sequence):
    tagSet = univ.Sequence.tagSet.tagExplicitly(
        tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 2)
    )
    componentType = namedtype.NamedTypes(
        namedtype.NamedType('name', char.PrintableString()),
        namedtype.NamedType('age', univ.Integer())
    )


# ===== 协议版本 2 =====
class ExplicitPersonV2(univ.Sequence):
    tagSet = univ.Sequence.tagSet.tagExplicitly(
        tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 2)
    )
    componentType = namedtype.NamedTypes(
        namedtype.NamedType('name', char.PrintableString()),
        namedtype.NamedType('age', univ.Integer()),
        namedtype.OptionalNamedType('email', char.IA5String())  # 新增字段
    )


# 创建测试数据
def create_test_data():
    # 创建实例
    explicit_v1 = ExplicitPersonV1()
    explicit_v2 = ExplicitPersonV2()

    # 设置 V1 数据
    explicit_v1['name'] = 'John Doe'
    explicit_v1['age'] = 30

    # 设置 V2 数据 (新增 email 字段)
    explicit_v2['name'] = 'John Doe'
    explicit_v2['age'] = 30
    explicit_v2['email'] = 'john@example.com'

    return {
        'explicit_v1': explicit_v1,
        'explicit_v2': explicit_v2
    }


# 测试兼容性
def test_compatibility():
    data = create_test_data()

    # 编码数据
    encoded = {
        'explicit_v1': encoder.encode(data['explicit_v1']),
        'explicit_v2': encoder.encode(data['explicit_v2'])
    }

    # 打印编码结果
    print("=== 编码结果 ===")
    for name, der in encoded.items():
        print(f"{name}: {binascii.hexlify(der).decode('ascii')}")

    # 兼容性测试：V1 解析 V2 数据
    print("\n=== V1 解析 V2 数据 ===")
    try:
        decoded, rest = decoder.decode(encoded['explicit_v2'], asn1Spec=ExplicitPersonV1())
        status = f"成功 (剩余: {len(rest)} 字节)"
        content = decoded.prettyPrint()
    except Exception as e:
        status = f"失败: {e}"
        content = ""

    print(f"ExplicitPersonV1 解析 ExplicitPersonV2: {status}")
    if content:
        print(f"  内容: {content}")

    # 兼容性测试：V2 解析 V1 数据
    print("\n=== V2 解析 V1 数据 ===")
    try:
        decoded, rest = decoder.decode(encoded['explicit_v1'], asn1Spec=ExplicitPersonV2())
        status = f"成功 (剩余: {len(rest)} 字节)"
        content = decoded.prettyPrint()
    except Exception as e:
        status = f"失败: {e}"
        content = ""

    print(f"ExplicitPersonV2 解析 ExplicitPersonV1: {status}")
    if content:
        print(f"  内容: {content}")


# 运行测试
if __name__ == "__main__":
    test_compatibility()